/* Copyright (c) [2020] [ylc]. Licensed under Apache-2.0 License. */

#include "SD3078.h"
#include "i2cDriveM.h"
#include "timestamp.h"

//读和写之间必须要有0.5s间隔，否则写无效

mI2CTypedef_t SDI2c;

static void i2c_Delay(void){
	u16 i;
	for(i=0;i<10;i++){
		__NOP();
	}
}

static void i2c_SdaH(void){
	gpio_bit_set(GPIOC,GPIO_PIN_14);
}

static void i2c_SdaL(void){
	gpio_bit_reset(GPIOC,GPIO_PIN_14);
}

static void i2c_SclH(void){
	gpio_bit_set(GPIOC,GPIO_PIN_15);
}

static void i2c_SclL(void){
	gpio_bit_reset(GPIOC,GPIO_PIN_15);
}

static u8 i2c_ReadSda(void){
	return gpio_input_bit_get(GPIOC,GPIO_PIN_14);
}

static u8 i2c_ReadScl(void){
	return 0;
}

//初始化i2c驱动
void sd_i2c_init(void)
{								
	SDI2c.IIC_InitPort=0;							//IO在gpio.c中初始化
	SDI2c.IIC_Delay=i2c_Delay;
	SDI2c.IIC_SDA_H=i2c_SdaH;
	SDI2c.IIC_SDA_L=i2c_SdaL;
	SDI2c.IIC_SCL_H=i2c_SclH;
	SDI2c.IIC_SCL_L=i2c_SclL;
	SDI2c.IIC_READ_SDA=i2c_ReadSda;
	SDI2c.IIC_READ_SCL=i2c_ReadScl;
}
//从uWriteAddress地址开始写入len字节数据
void sd_i2c_write(u8 uWriteAddress,u8 *buf,u8 len)
{
	i2c_Start(&SDI2c);
	i2c_SendByte(&SDI2c,SD_I2C_ADDR|I2C_WR);
	i2c_WaitAck(&SDI2c);
	i2c_SendByte(&SDI2c,(uWriteAddress) & 0xFF);
	i2c_WaitAck(&SDI2c);
	while(len--){
		i2c_SendByte(&SDI2c,*buf++);
		i2c_WaitAck(&SDI2c);
	}
	i2c_Stop(&SDI2c);
}
//从uWriteAddress地址开始读出len字节数据
u8 sd_i2c_read(u8 uReadAddress,u8 *buf,u8 len)
{
	i2c_Start(&SDI2c);
	i2c_SendByte(&SDI2c,SD_I2C_ADDR|I2C_WR);
	if(1==i2c_WaitAck(&SDI2c)){	//ERROR
		return 0;
	}
	i2c_SendByte(&SDI2c,uReadAddress);
	if(1==i2c_WaitAck(&SDI2c)){	//ERROR
		return 0;
	}
	i2c_Start(&SDI2c);
	i2c_SendByte(&SDI2c,SD_I2C_ADDR|I2C_RD);
	if(1==i2c_WaitAck(&SDI2c)){	//ERROR
		return 0;
	}
	while(len-->1){
		*buf++ = i2c_ReadByte(&SDI2c);
		i2c_Ack(&SDI2c);
	}
	*buf++ = i2c_ReadByte(&SDI2c);
	i2c_NAck(&SDI2c);
	i2c_Stop(&SDI2c);
	return 1;//正常返回
}
//写允许
void sd3078_write_enable(void)
{
	u8 buf[3]={0x84,0x80};
	sd_i2c_write(XRTC_CTR2,buf+1,1);
	sd_i2c_write(XRTC_CTR1,buf,1);
}
//写禁止
void sd3078_write_disable(void)
{
	u8 buf[2]={0,0};
	sd_i2c_write(XRTC_CTR1,buf,2);
}
//通过时间戳设置外部时钟时间
void sd_set_time(u32 timestamp)
{
	u8 timebuf[7];
	u8 rtc_timebuf[7];
	getNowTime(timestamp,timebuf);
	rtc_timebuf[0]=(timebuf[5]/10<<4)+timebuf[5]%10;		//秒
	rtc_timebuf[1]=(timebuf[4]/10<<4)+timebuf[4]%10;		//分
	rtc_timebuf[2]=((timebuf[3]/10<<4)+timebuf[3]%10)|0x80;	//时  最高位置一，代表24小时制
	rtc_timebuf[3]=timebuf[6];		//星期
	rtc_timebuf[4]=(timebuf[2]/10<<4)+timebuf[2]%10;		//日
	rtc_timebuf[5]=(timebuf[1]/10<<4)+timebuf[1]%10;		//月
	rtc_timebuf[6]=(timebuf[0]/10<<4)+timebuf[0]%10;		//年
//	delay_ms(500);
	sd3078_write_enable();
	sd_i2c_write(0,rtc_timebuf,7);
	sd3078_write_disable();
}
//获取时间到时间戳中
void sd_get_time(u32 *timestamp)
{
	u8 timebuf[7];
	u8 rtc_timebuf[7];
	sd_i2c_read(0,rtc_timebuf,7);
	
	timebuf[5]=(rtc_timebuf[0]>>4)*10+(rtc_timebuf[0]&0x0F);		//秒
	timebuf[4]=(rtc_timebuf[1]>>4)*10+(rtc_timebuf[1]&0x0F);		//分
	timebuf[3]=((rtc_timebuf[2]&0x70)>>4)*10+(rtc_timebuf[2]&0x0F);	//时  最高位置一，代表24小时制
	timebuf[2]=(rtc_timebuf[4]>>4)*10+(rtc_timebuf[4]&0x0F);		//日
	timebuf[1]=(rtc_timebuf[5]>>4)*10+(rtc_timebuf[5]&0x0F);		//月
	timebuf[0]=(rtc_timebuf[6]>>4)*10+(rtc_timebuf[6]&0x0F);		//年
	*timestamp=getTimeStamp(timebuf);
}
//设置倒计时中断
void sd_set_countdown_it(XRTC_CountDown_Def *CountDown_Init)					
{
	u8 buf[6];
	u8 tem=0xF0;
	buf[0] = (CountDown_Init->IM<<6)|0xB4;							//10H
	buf[1] = CountDown_Init->d_clk<<4;								//11H
	buf[2] = 0;														//12H
	buf[3] = CountDown_Init->init_val & 0x0000FF;					//13H
	buf[4] = (CountDown_Init->init_val & 0x00FF00) >> 8;//14H
	buf[5] = (CountDown_Init->init_val & 0xFF0000) >> 16;//15H
	sd_i2c_write(XRTC_CTR2,&tem,1);
	sd_i2c_write(XRTC_CTR2,buf,6);
}
//设置报警中断
void sd_set_alarm_it(u8 Enable_config, XRTC_Time_Def *psRTC)					
{
	u8 buf[10];
	buf[0] = psRTC->second;
	buf[1] = psRTC->minute;
	buf[2] = psRTC->hour;
	buf[3] = 0;
	buf[4] = psRTC->day;
	buf[5] = psRTC->month;
	buf[6] = psRTC->year;
	buf[7] = Enable_config;
	buf[8] = 0xFF;
	buf[9] = 0x92;	
	sd_i2c_write(XRTC_Alarm_SC,buf,10);
}
//设置RTC频率中断，从INT脚输出频率方波
void sd_set_frq_it(enum XRTC_Freq F_Out)					
{
	u8 buf[2];
	buf[0] = 0xA1;
	buf[1] = F_Out;
	sd_i2c_write(XRTC_CTR2,buf,2);
}
//禁止中断
//int_EN：中断类型 INTDE、INTDE、INTDE
void sd_clear_it(u8 int_EN)         
{
	u8 buf;
	buf = 0x80 & (~int_EN);
	sd_i2c_write(XRTC_CTR2,&buf,1);
}
//初始化
void sd3078_init(void)
{
	sd_i2c_init();							//注册I2C驱动
	//sd_get_time((u32*)&mSystem.timestamp);	//获取外部时钟时间
	XRTC_CountDown_Def tm;
	tm.IM=1;
	tm.d_clk=S_4096Hz;
	tm.init_val=40960;
	sd_set_countdown_it(&tm);
}


